<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      li {
        list-style: none;
      }
      div {
        width: 500px;
        height: 300px;
        margin: 50px auto;
        border: 5px solid #000;
        border-radius: 5px;
        position: relative;
        overflow: hidden;
      }
      div > ul {
        width: 300%;
        height: 100%;
        position: absolute;
        top: 0;
      }
      div > ul > li {
        width: 500px;
        height: 100%;
        float: left;
      }
      div img {
        width: 100%;
        height: 100%;
      }
      span {
        width: 40px;
        height: 50px;
        position: absolute;
        background-color: rgba(35, 157, 222, 0.3);
        font-size: 30px;
        text-align: center;
        line-height: 50px;
        color: #fff;
        cursor: pointer;
      }
      .left {
        left: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      .right {
        right: 0;
        top: 50%;
        transform: translateY(-50%);
      }
      ol {
        height: 20px;
        background-color: #fff;
        position: absolute;
        bottom: 10px;
        left: 50%;
        transform: translateX(-50%);
        display: flex;
        justify-content: space-evenly;
        align-items: center;
        border-radius: 10px;
      }
      ol > li {
        width: 10px;
        height: 10px;
        background-color: pink;
        border-radius: 50%;
        margin: 10px;
        cursor: pointer;
      }
      ol > li.active {
        background-color: skyblue;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <ul>
        <li><img src="./img/1.jfif" alt="" /></li>
        <li><img src="./img/2.jfif" alt="" /></li>
        <li><img src="./img/3.jfif" alt="" /></li>
      </ul>
      <span class="left">&lt;</span><span class="right">&gt;</span>
      <ol></ol>
    </div>
  </body>
  <script>
    function Banner(cname) {
      this.box = document.querySelector("." + cname);
      this.rightBtn = this.box.querySelector(".right");
      this.leftBtn = this.box.querySelector(".left");
      this.circles = this.box.querySelector("ol");
      this.imgBox = this.box.querySelector("ul");
      this.imgs = this.box.querySelectorAll("ul>li>img");
      this.onOff = true;
      this.num = 1;
    }
    Banner.prototype.init = function () {
      this.rightClick();
      this.start();
      this.leftClick();
      this.circleClick();
      this.autoPlay();
    };
    Banner.prototype.rightMove = function () {
      if (this.onOff) {
        this.num++;
        this.onOff = false;
        this.animate(
          this.imgBox,
          {
            left: -this.imgs[0].offsetWidth * this.num + "px",
          },
          () => {
            this.onOff = true;
            if (this.num === 4) {
              this.num = 1;
              this.imgBox.style.left =
                -this.imgs[0].offsetWidth * this.num + "px";
            }
            for (var i = 0; i < this.circles.children.length; i++) {
              this.circles.children[i].classList.remove("active");
            }
            this.circles.children[this.num - 1].classList.add("active");
          }
        );
      }
    };
    Banner.prototype.start = function () {
      var lastImg = this.imgBox.children[0].cloneNode(true);
      var firstImg =
        this.imgBox.children[this.imgBox.children.length - 1].cloneNode(true);
      this.imgBox.insertBefore(firstImg, this.imgBox.children[0]);
      this.imgBox.appendChild(lastImg);
      this.imgBox.style.width =
        this.imgBox.children.length * this.imgs[0].offsetWidth + "px";
      this.imgBox.style.left = -this.imgs[0].offsetWidth + "px";
      for (var i = 0; i < this.imgs.length; i++) {
        var circle = document.createElement("li");
        this.circles.appendChild(circle);
      }
      this.circles.children[0].classList.add("active");
    };
    Banner.prototype.rightClick = function () {
      this.rightBtn.onclick = () => {
        this.rightMove();
      };
    };

    Banner.prototype.circleClick = function () {
      this.circles.onclick = (event) => {
        for (var i = 0; i < this.circles.children.length; i++) {
          this.circles.children[i].classList.remove("active");
        }
        event.target.classList.add("active");
        this.onOff = false;
        for (var i = 0; i < this.circles.children.length; i++) {
          if (this.circles.children[i].className === "active") {
            this.num = i + 1;
          }
        }
        this.animate(
          this.imgBox,
          {
            left: -this.imgs[0].offsetWidth * this.num + "px",
          },
          () => {
            this.onOff = true;
          }
        );
      };
    };
    Banner.prototype.leftClick = function () {
      this.leftBtn.onclick = () => {
        if (this.onOff) {
          this.num--;
          this.onOff = false;
          this.animate(
            this.imgBox,
            {
              left: -this.imgs[0].offsetWidth * this.num + "px",
            },
            () => {
              this.onOff = true;
              if (this.num === 0) {
                this.num = 3;
                this.imgBox.style.left =
                  -this.imgs[0].offsetWidth * this.num + "px";
              }
              for (var i = 0; i < this.circles.children.length; i++) {
                this.circles.children[i].classList.remove("active");
              }
              this.circles.children[this.num - 1].classList.add("active");
            }
          );
        }
      };
    };
    Banner.prototype.autoPlay = function () {
      var timer = setInterval(() => {
        this.rightMove();
      }, 2000);
      this.box.onmouseenter = () => {
        clearInterval(timer);
      };
      this.box.onmouseleave = () => {
        timer = setInterval(() => {
          this.rightMove();
        }, 2000);
      };
    };
    Banner.prototype.animate = function (ele, obj, stop) {
      var index = 0;
      for (var key in obj) {
        index++;
        (function (key) {
          var target = key === "opacity" ? obj[key] * 100 : parseInt(obj[key]);
          var current = getComputedStyle(ele)[key];
          current = key === "opacity" ? current * 100 : parseInt(current);
          var step = (target - current) / 10;
          var timer = setInterval(() => {
            current += step;
            ele.style[key] = key === "opacity" ? current / 100 : current + "px";
            if (current === target) {
              index--;
              clearInterval(timer);
              if (index === 0) {
                stop();
              }
            }
          }, 50);
        })(key);
      }
    };
    var banner = new Banner("box");
    banner.init();
  </script>
</html>
